home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 276-300 / 299 / hangman / hangman.c < prev    next >
C/C++ Source or Header  |  1995-03-14  |  9KB  |  438 lines

  1. /* hangman.c - a hangman game similar to one seen on some *nix machines.*
  2.  *                                    *
  3.  * hangman [wordlist]                            *
  4.  *        if wordlist is not specified, reads words in current     *
  5.  *        directory if it exists, else reads dict:words.        *
  6.  *                                    *
  7.  * hangman (C) 1989 by Gary L. Brant                    *
  8.  *                                    *
  9.  * :ts=8                                */
  10.  
  11. #include <ctype.h>
  12. #include <stdio.h>
  13. #include <time.h>
  14. #include <stat.h>
  15.  
  16. char word[30];
  17. char dead_man[][4] = {
  18.     " O ",
  19.     "/|\\",
  20.     " | ",
  21.     "/ \\"
  22. };
  23.  
  24. char guessed[28];    /* letters already guessed */
  25. int count = 0;        /* count of letters in guessed */
  26. char blimp[30];        /* string of -'s length of word */
  27. char dictionary[30];    /* file name of dictionary */
  28. float curavg = 0.0;
  29. float overavg = 0.0;
  30. int wordno = 0;
  31. long totalwrong = 0L;
  32. int done = 0;
  33. int raw_mode = 0;    /* true if currently in raw mode */
  34. FILE *dict, *fopen ();
  35. struct stat statbuf;
  36. long size;
  37.  
  38.  
  39. main (argc, argv)
  40. int argc;
  41. char *argv[];
  42. {
  43.     int i;
  44.  
  45.     if (argc > 1) {
  46.     if ((dict = fopen (argv[1], "r")) == NULL) {
  47.         printf ("can't open %s\n", argv[1]);
  48.         exit (20);
  49.     } else
  50.         strcpy (dictionary, argv[1]);
  51.     } else if ((dict = fopen ("words", "r")) == NULL) {
  52.     if ((dict = fopen ("dict:words", "r")) == NULL) {
  53.         printf ("can't find dictionary\n");
  54.         exit (20);
  55.     } else
  56.         strcpy (dictionary, "dict:words");
  57.     } else
  58.     strcpy (dictionary, "words");
  59.     if ((stat (dictionary, &statbuf)) == -1) {
  60.     printf ("can't get info for %s\n", dictionary);
  61.     quit (10);
  62.     }
  63.     size = statbuf.st_size;
  64.     srand ((int) time ((long *) 0));    /* use time as random seed */
  65.  
  66.     do {        /* loop until user says no more */
  67.     getword ();    /* get word from dictionary */
  68.  
  69.     set_raw ();
  70.     raw_mode = 1;
  71.     hangman ();    /* play one word game */
  72.     newgame ();
  73.     set_con ();
  74.     raw_mode = 0;
  75.     } while (!done);
  76.  
  77.     quit (0);
  78. }
  79.  
  80.  
  81. /* get a random number. */
  82.  
  83. long getran () 
  84. {
  85.     long time ();
  86.     unsigned long i, j;
  87.  
  88.     i = rand ();
  89.     j = rand ();
  90.     i += 65536 * j;    /* fabricate a random long int */
  91.     return (i);
  92. }
  93.  
  94.  
  95. /* get a word from the dictionary for use in the game */
  96.  
  97. getword ()
  98. {
  99.     register int i, len;
  100.     long num;
  101.     long position;
  102.  
  103.     for (;;) {
  104.     num = getran ();    /* get an random long integer */ 
  105.     position = num % size;
  106.  
  107.     if ((fseek (dict, position, 0)) != 0) {
  108.         printf ("can't seek on %s\n", dictionary);
  109.         quit (10);
  110.     }
  111.     fgets (word, 29, dict);
  112.     if (fgets (word, 29, dict) == NULL)
  113.         continue;
  114.  
  115.     if ((len = strlen (word) - 1) < 4)
  116.         continue;
  117.  
  118.     for (i = 0; i < len; i++)
  119.         if (word[i] < 'a' || word[i] > 'z')
  120.         goto nogood;
  121.     word[len] = '\0';
  122.     return;            /* return word found */
  123. nogood:
  124.     continue;
  125.     }
  126. }
  127.  
  128.  
  129. /* play one word game, return as soon as guesses used up or word guessed.
  130.  * Display a congratulatory message before exiting if player guessed the
  131.  * word, else display the word.
  132.  */
  133.  
  134. hangman ()
  135. {
  136.     char guess;            /* the current guess */
  137.     int i;
  138.     int togo;            /* number of letters still to be guessed */
  139.     int wrong = 0;        /* number of incorrect guesses */
  140.  
  141.     char getcharacter ();    /* get user's input */
  142.  
  143.  
  144.     nextword ();
  145.     redraw ();
  146.  
  147.     togo = strlen (word);
  148.     while (togo > 0) {        /* haven't guessed all the characters */
  149.     int dup = 0;        /* if letter was guessed before */
  150.     for (;;) {        /* do until guess is a character */
  151.         scr_curs (12, 8);
  152.         scr_eol ();
  153.         fflush (stdout);
  154.  
  155.         guess = getcharacter ();
  156.         putc (guess, stdout);
  157.         if (guess == '\f')    /* redraw screen if ^L */
  158.         redraw    ();
  159.         else if (!isalpha (guess)) { /* disallow non-alpha characters */
  160.         scr_beep ();
  161.         scr_curs (12, 8);
  162.         scr_eol ();
  163.         scr_curs (13, 0);
  164.         fputs ("Not a valid guess, ", stdout);
  165.         if (guess < ' ') {
  166.             char bad[4];
  167.  
  168.             bad[0] = '^';
  169.             bad[1] = guess + 'A' - 1;
  170.             bad[2] = '\0';
  171.             fputs (bad, stdout);
  172.         } else
  173.             putc (guess, stdout);
  174.         } else
  175.         break;            /* drop out of loop if alpha */
  176.     }
  177.  
  178.     for (i = 0; guessed[i]; i++)
  179.         if (guess == guessed[i]) {
  180.         dup = 1;
  181.         break;
  182.         }
  183.     scr_curs (13, 0);
  184.     scr_eol ();
  185.     if (dup) {            /* if previously guessed */
  186.         printf ("Already guessed %c", guess);
  187.         dup = 0;
  188.     } else {
  189.         int inword = 0;        /* if guess in word */
  190.         for (i = 0; word[i]; i++) {
  191.         if (guess == word[i]) {
  192.             inword = 1;
  193.             togo--;
  194.             blimp[i] = guess;
  195.             scr_curs (11, i+8);
  196.             putc (guess, stdout);    /* place letter in word */
  197.             if (togo == 0) {        /* if word completed */
  198.             insert (guess);
  199.             scr_curs (13, 0);
  200.             fputs ("You got it!", stdout);
  201.             return;
  202.             }
  203.         }
  204.         }
  205.         if (!inword) {
  206.         wrong++;            /* scorekeeping */
  207.         totalwrong++;
  208.         curavg += 1.0 / ((float) wordno);
  209.         scr_curs (6, 49);    /* update current average on screen */
  210.         printf ("%8.4f", curavg);
  211.         switch (wrong) {
  212.         case 1: scr_curs (3, 10);
  213.             putc ('O', stdout);
  214.             dead_man[0][1] = 'O';
  215.             break;
  216.         case 2: scr_curs (4, 10);
  217.             putc ('|', stdout);
  218.             dead_man[1][1] = '|';
  219.             break;
  220.         case 3: scr_curs (5, 10);
  221.             putc ('|', stdout);
  222.             dead_man[2][1] = '|';
  223.             break;
  224.         case 4: scr_curs (6, 9);
  225.             putc ('/', stdout);
  226.             dead_man[3][0] = '/';
  227.             break;
  228.         case 5: scr_curs (4, 9);
  229.             putc ('/', stdout);
  230.             dead_man[1][0] = '/';
  231.             break;
  232.         case 6: scr_curs (4, 11);
  233.             putc ('\\', stdout);
  234.             dead_man[1][2] = '\\';
  235.             break;
  236.         case 7: scr_curs (6, 11);
  237.             putc ('\\', stdout);
  238.             dead_man[3][2] = '\\';
  239.             scr_curs (13, 0);
  240.             fputs ("The word was:  ", stdout);
  241.             fputs (word, stdout);
  242.             return;
  243.         }
  244.         }
  245.         insert (guess);
  246.     }
  247.     }
  248.     return;
  249. }
  250.  
  251.  
  252. /* game over; inquire from player whether to play another */
  253.  
  254. newgame ()
  255. {
  256.     char c;
  257.  
  258.     scr_curs (14, 0);
  259.     fputs ("Another word? ", stdout);
  260.     for (;;) {
  261.     fflush (stdout);
  262.     c = getcharacter ();
  263.     if (c == 'n') {
  264.         done = 1;
  265.         return;
  266.     } else if (c == 'y')
  267.         return;
  268.     scr_curs (15, 0);
  269.     fputs ("Please type 'y' or 'n'", stdout);
  270.     scr_curs (14, 15);
  271.     }
  272. }
  273.  
  274.  
  275. /* redraw display at beginning of new word or at user request (^L) */
  276.  
  277. redraw ()
  278. {
  279.     int i;
  280.  
  281.     scr_clear ();
  282.  
  283.     scr_curs (1, 5);
  284.     fputs ("______", stdout);
  285.  
  286.     scr_curs (2, 5);
  287.     fputs ("|    |", stdout);
  288.  
  289.     scr_curs (3, 5);
  290.     putc ('|', stdout);
  291.     scr_curs (3, 10);
  292.     putc (dead_man[0][1], stdout);
  293.     scr_curs (3, 32);
  294.     fputs ("Guessed:  ", stdout);
  295.     fputs (guessed, stdout);
  296.  
  297.     scr_curs (4, 5);
  298.     putc ('|', stdout);
  299.     scr_curs (4, 9);
  300.     for (i = 0; i < 3; i++)
  301.     putc (dead_man[1][i], stdout);
  302.  
  303.     scr_curs (5, 5);
  304.     putc ('|', stdout);
  305.     scr_curs (5, 9);
  306.     for (i = 0; i < 3; i++)
  307.     putc (dead_man[2][i], stdout);
  308.     scr_curs (5, 32);
  309.     printf ("Word #:  %d", wordno);
  310.  
  311.     scr_curs (6, 5);
  312.     putc ('|', stdout);
  313.     scr_curs (6, 9);
  314.     for (i = 0; i < 3; i++)
  315.     putc (dead_man[3][i], stdout);
  316.     scr_curs (6, 32);
  317.     printf ("Current Average: %8.4f", curavg);
  318.  
  319.     scr_curs (7, 3);
  320.     fputs ("__|_____", stdout);
  321.     scr_curs (7, 32);
  322.     printf ("Overall Average: %8.4f", overavg);
  323.  
  324.     scr_curs (8, 3);
  325.     putc ('|', stdout);
  326.     scr_curs (8, 10);
  327.     fputs ("|___", stdout);
  328.  
  329.     scr_curs (9, 3);
  330.     fputs ("|_________|", stdout);
  331.  
  332.     scr_curs (11, 1);
  333.     fputs ("Word:  ", stdout);
  334.     fputs (blimp, stdout);
  335.  
  336.     scr_curs (12, 0);
  337.     fputs ("Guess:", stdout);
  338.  
  339.     fflush (stdout);
  340. }
  341.  
  342.  
  343. /* reset stuff for next word */
  344.  
  345. nextword ()
  346. {
  347.     int i, j;
  348.  
  349.     for (i = 0; i < 4; i++)
  350.     for (j = 0; j < 3; j++)
  351.         dead_man[i][j] = ' ';
  352.  
  353.     for (i = 0; i < strlen (word); i++)
  354.     blimp[i] = '-';
  355.     blimp[i] = '\0';
  356.  
  357.     for (i = 0; i < 28; i++)
  358.     guessed[i] = '\0';
  359.  
  360.     count = 0;
  361.     wordno++;
  362.     overavg = curavg;
  363.     curavg = ((float) totalwrong) / ((float) wordno);
  364. }
  365.  
  366.  
  367. /* get user's input */
  368.  
  369. char getcharacter ()
  370. {
  371.  
  372.     while (!WaitForChar (Input (), 100L) &&
  373.        stdin->_bp >= stdin->_bend);
  374.     return (tolower (getc (stdin)));
  375. }
  376.  
  377.  
  378. /* insert letter just guessed into list of guessed letters; also update list
  379.  * on screen for player.
  380.  */
  381.  
  382. insert (guess)
  383. register char guess;
  384. {
  385.     if (count == 0) {            /* first guess ? */
  386.     guessed[count++] = guess;
  387.     scr_curs (3, 42);
  388.     putc (guess, stdout);
  389.     } else {
  390.     register int i, j;
  391.  
  392.     for (i = 0; i < count; i++)
  393.         if (guessed[i] > guess)
  394.         break;
  395.     for (j = count; j > i; j--)
  396.         guessed[j] = guessed[j-1];
  397.     guessed[i] = guess;        /* add the guess to list of */
  398.                     /* previously guessed letters*/
  399.     scr_curs (3, i+42);
  400.     fputs (&guessed[i], stdout);    /* update list on screen */
  401.     count++;
  402.     }
  403. }
  404.  
  405.  
  406. /* needed, since Manx version apparently doesn't work */
  407.  
  408.  scr_eol ()
  409. {
  410.     static char clr[] = {0x9b, 'K', '\0'};
  411.  
  412.     fputs (clr, stdout);
  413. }
  414.  
  415.  
  416. /* in order to have a chance at cleaning up & exiting gracefully */
  417.  
  418. _abort ()
  419. {
  420.     puts ("^C");
  421.     quit (0);
  422. }
  423.  
  424.  
  425. quit (code)
  426. int code;
  427. {
  428.     if (dict)
  429.     fclose (dict);
  430.     set_con ();
  431.     exit (code);
  432. }
  433.  
  434.  
  435. _wb_parse ()
  436. {
  437. }
  438.